home *** CD-ROM | disk | FTP | other *** search
- // VirtualDub - Video processing and capture application
- // Copyright (C) 1998-2001 Avery Lee
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation; either version 2 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- #include "VirtualDub.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <crtdbg.h>
- #include <windows.h>
- #include <commctrl.h>
-
- #include "resource.h"
- #include "list.h"
- #include "gui.h"
- #include "oshelper.h"
- #include "capspill.h"
-
- CapSpillDrive::CapSpillDrive() {
- path = NULL;
- threshold = priority = 0;
- }
-
- CapSpillDrive::~CapSpillDrive() {
- delete path;
- }
-
- void CapSpillDrive::setPath(char *s) {
- delete path;
- path = s;
- }
-
- char *CapSpillDrive::makePath(char *buf, const char *fn) const {
- char *t, *s;
-
- s = path;
- t = buf;
- while(*t++ = *s++);
-
- --t;
-
- if (t>buf) {
- if (t[-1] != '\\' && t[-1]!=':')
- *t++ = '\\';
- }
-
- strcpy(t, fn);
-
- return buf;
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
- extern HINSTANCE g_hInst;
- extern const char g_szError[];
-
- static List2<CapSpillDrive> g_spillDrives;
-
- extern long g_lSpillMinSize = 50;
- extern long g_lSpillMaxSize = 1900;
-
- ///////////////////////////////////////////////////////////////////////////
-
- __int64 CapSpillGetFreeSpace() {
- CapSpillDrive *pcsd = g_spillDrives.AtHead();
- CapSpillDrive *pcsd_next;
- __int64 i64Total = 0, i64Free;
-
- while(pcsd_next = pcsd->NextFromHead()) {
-
- // Probably shouldn't continuously query free space on a UNC path.
-
- if (pcsd->path[0] != '\\' || pcsd->path[1] != '\\') {
- i64Free = MyGetDiskFreeSpace(pcsd->path);
-
- if (i64Free != -1)
- i64Total += i64Free;
- }
-
- pcsd = pcsd_next;
- }
-
- return i64Total;
- }
-
- CapSpillDrive *CapSpillPickDrive(bool fAudio) {
- // Poll drives, look for the highest priority with the most free space
-
- CapSpillDrive *pcsd = g_spillDrives.AtHead();
- CapSpillDrive *pcsd_next;
- CapSpillDrive *pcsd_best = NULL;
- __int64 i64Free, i64FreeBest = 0;
-
- while(pcsd_next = pcsd->NextFromHead()) {
-
- i64Free = MyGetDiskFreeSpace(pcsd->path);
-
- if ((i64Free>>20) > pcsd->threshold + g_lSpillMinSize &&
- (!pcsd_best || pcsd->priority > pcsd_best->priority
- || (pcsd->priority == pcsd_best->priority && i64Free > i64FreeBest))) {
-
- i64FreeBest = i64Free;
- pcsd_best = pcsd;
- }
-
- pcsd = pcsd_next;
- }
-
- return pcsd_best;
- }
-
- CapSpillDrive *CapSpillFindDrive(const char *path) {
- CapSpillDrive *pcsd = g_spillDrives.AtHead();
- CapSpillDrive *pcsd_next;
- CapSpillDrive *pcsd_best = NULL;
-
- while(pcsd_next = pcsd->NextFromHead()) {
- const char *s = path, *t = pcsd->path;
- char c, d;
-
- while((c=*s++)==(d=*t++) && c)
- ;
-
- if ((!c && !d) || (c=='/' && !d) || (!c && d=='/'))
- return pcsd;
-
- pcsd = pcsd_next;
- }
-
- return NULL;
- }
-
- void CapSpillSaveToRegistry() {
- DWORD dwNumDrives = 0;
- CapSpillDrive *pcsd = g_spillDrives.AtHead(), *pcsd_next;
- char szDriveConfig[512];
- char szValueName[32];
-
- while(pcsd_next = (CapSpillDrive *)pcsd->NextFromHead()) {
- sprintf(szValueName, "Drive %d", ++dwNumDrives);
- sprintf(szDriveConfig, "%d,%d,%s", pcsd->priority, pcsd->threshold, pcsd->path);
-
- SetConfigString("Capture\\Spill Drives", szValueName, szDriveConfig);
-
- pcsd = pcsd_next;
- }
- SetConfigDword("Capture\\Spill Drives", "Number", dwNumDrives);
- SetConfigDword("Capture\\Spill Drives", "Minimum file size", g_lSpillMinSize);
- SetConfigDword("Capture\\Spill Drives", "Maximum file size", g_lSpillMaxSize);
- }
-
- void CapSpillRestoreFromRegistry() {
- DWORD dwNumDrives;
- DWORD dwDrive=1;
- char szValueName[32];
- char szDriveConfig[512];
- CapSpillDrive *pcsd;
-
- QueryConfigDword("Capture\\Spill Drives", "Minimum file size", (DWORD *)&g_lSpillMinSize);
- QueryConfigDword("Capture\\Spill Drives", "Maximum file size", (DWORD *)&g_lSpillMaxSize);
-
- if (!QueryConfigDword("Capture\\Spill Drives", "Number", &dwNumDrives))
- return;
-
- while(pcsd = g_spillDrives.RemoveTail())
- delete pcsd;
-
- while(dwDrive <= dwNumDrives) {
- sprintf(szValueName, "Drive %d", dwDrive);
-
- if (QueryConfigString("Capture\\Spill Drives", szValueName, szDriveConfig, sizeof szDriveConfig)) {
- int pri, thresh, pos;
-
- if (2==sscanf(szDriveConfig, "%d,%d%n", &pri, &thresh, &pos) && szDriveConfig[pos]==',') {
- pcsd = new CapSpillDrive();
- char *pszPath = strdup(szDriveConfig+pos+1);
-
- if (!pcsd || !pszPath) {
- delete pcsd;
- freemem(pszPath);
- } else {
- pcsd->priority = pri;
- pcsd->threshold = thresh;
- pcsd->setPath(pszPath);
- g_spillDrives.AddTail(pcsd);
- }
- }
- }
-
- ++dwDrive;
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
- static LRESULT APIENTRY LVWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
- static void LVBeginEdit(HWND hwndLV, int index, int subitem);
-
- ///////////////////////////////////////////////////////////////////////////
-
- bool CapSpillAdd(HWND hwnd, CapSpillDrive *pcsd, bool fAddList) {
- LVITEM lvi;
-
- lvi.mask = LVIF_TEXT | LVIF_PARAM;
- lvi.iItem = 0;
- lvi.iSubItem = 0;
- lvi.pszText = LPSTR_TEXTCALLBACK;
- lvi.lParam = (LPARAM)pcsd;
-
- if (-1 == ListView_InsertItem(hwnd, &lvi))
- return false;
-
- if (fAddList)
- g_spillDrives.AddTail(pcsd);
-
- return true;
- }
-
- BOOL CALLBACK CaptureSpillDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) {
- switch(msg) {
- case WM_INITDIALOG:
- {
- HWND hwndItem;
- LVCOLUMN lvc;
- RECT r;
- CapSpillDrive *pcsd, *pcsd_next;
-
- hwndItem = GetDlgItem(hdlg, IDC_SPILL_DRIVES);
- GetClientRect(hwndItem, &r);
-
- lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
- lvc.fmt = LVCFMT_LEFT;
- lvc.cx = 50;
- lvc.pszText = "Priority";
-
- ListView_InsertColumn(hwndItem, 0, &lvc);
-
- lvc.pszText = "Threshold";
- lvc.cx = 100;
- ListView_InsertColumn(hwndItem, 1, &lvc);
-
- lvc.pszText = "Path";
- lvc.cx = r.right - r.left - 150;
- ListView_InsertColumn(hwndItem, 2, &lvc);
-
- pcsd = (CapSpillDrive *)g_spillDrives.AtHead();
-
- while(pcsd_next = (CapSpillDrive *)pcsd->NextFromHead()) {
- CapSpillAdd(hwndItem, pcsd, false);
- pcsd = pcsd_next;
- }
-
- guiSubclassWindow(hwndItem, LVWndProc);
-
- SetDlgItemInt(hdlg, IDC_MIN_SIZE, g_lSpillMinSize, FALSE);
- SetDlgItemInt(hdlg, IDC_MAX_SIZE, g_lSpillMaxSize, FALSE);
- }
- return TRUE;
- case WM_COMMAND:
- switch(LOWORD(wParam)) {
- case IDOK:
- {
- BOOL fOk;
- LONG lMin, lMax;
-
- lMin = GetDlgItemInt(hdlg, IDC_MIN_SIZE, &fOk, FALSE);
- if (!fOk || lMin > 2048) {
- SetFocus(GetDlgItem(hdlg, IDC_MIN_SIZE));
- MessageBox(hdlg, "Minimum size must be between 0 and 2048 megabytes.", g_szError, MB_OK);
- return TRUE;
- }
- lMax = GetDlgItemInt(hdlg, IDC_MAX_SIZE, &fOk, FALSE);
- if (!fOk || lMax < 50 && lMax > 2048) {
- SetFocus(GetDlgItem(hdlg, IDC_MAX_SIZE));
- MessageBox(hdlg, "Maximum size must be between 50 and 2048 megabytes.", g_szError, MB_OK);
- return TRUE;
- }
-
- g_lSpillMinSize = lMin;
- g_lSpillMaxSize = lMax;
- }
- CapSpillSaveToRegistry();
- EndDialog(hdlg, 0);
- return TRUE;
- case IDC_ADD:
- {
- CapSpillDrive *pcsd = new CapSpillDrive();
-
- if (!pcsd)
- return TRUE;
-
- pcsd->threshold = 50;
-
- if (!CapSpillAdd(GetDlgItem(hdlg, IDC_SPILL_DRIVES), pcsd, true))
- delete pcsd;
- }
- return TRUE;
- case IDC_DEL:
- {
- HWND hwndLV = GetDlgItem(hdlg, IDC_SPILL_DRIVES);
- int ind;
-
- ind = ListView_GetNextItem(hwndLV, -1, MAKELPARAM(LVNI_SELECTED,0));
-
- if (ind >= 0) {
- LVITEM lvi;
-
- lvi.iItem = ind;
- lvi.iSubItem = 0;
- lvi.mask = LVIF_PARAM;
-
- if (ListView_GetItem(hwndLV, &lvi)) {
- CapSpillDrive *pcsd = (CapSpillDrive *)lvi.lParam;
-
- pcsd->Remove();
- delete pcsd;
- }
-
- ListView_DeleteItem(hwndLV, ind);
- }
- }
- return TRUE;
- }
- break;
-
- case WM_NOTIFY:
- if (((NMHDR *)lParam)->idFrom == IDC_SPILL_DRIVES) {
- NMLVDISPINFO *pnldi = (NMLVDISPINFO *)lParam;
-
- if (pnldi->hdr.code == LVN_GETDISPINFO) {
- CapSpillDrive *pcsd, *pcsd_next = NULL;
- int i = pnldi->item.iItem;
-
- pcsd = (CapSpillDrive *)pnldi->item.lParam;
-
- if (!pcsd) {
- pnldi->item.pszText[0] = 0;
- return TRUE;
- }
-
- switch(pnldi->item.iSubItem) {
- case 0:
- _snprintf(pnldi->item.pszText, pnldi->item.cchTextMax, "%+d", pcsd->priority);
- break;
- case 1:
- _snprintf(pnldi->item.pszText, pnldi->item.cchTextMax, "%ldMb", pcsd->threshold);
- break;
- case 2:
- if (pcsd->path)
- pnldi->item.pszText = pcsd->path;
- else
- pnldi->item.pszText[0] = 0;
- break;
- default:
- pnldi->item.pszText[0] = 0;
- break;
- }
- }
- }
- return TRUE;
- }
- return FALSE;
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
- static HWND g_hwndBox;
- static HWND g_hwndEdit=NULL;
- static HWND g_hwndSpin=NULL;
- static CapSpillDrive *g_csdPtr;
- static int g_csdItem;
- static int g_index;
-
- int CALLBACK LVSorter(LPARAM lp1, LPARAM lp2, LPARAM lp) {
- CapSpillDrive *pcsd1 = (CapSpillDrive *)lp1;
- CapSpillDrive *pcsd2 = (CapSpillDrive *)lp2;
-
- if (pcsd1->priority > pcsd2->priority) return -1;
- else if (pcsd1->priority < pcsd2->priority) return 1;
- else if (pcsd1->threshold > pcsd2->threshold) return 1;
- else if (pcsd1->threshold < pcsd2->threshold) return -1;
- else if (pcsd1->path && pcsd2->path)
- return stricmp(pcsd1->path, pcsd2->path);
- else
- return 0;
- }
-
- static void LVDestroyEdit(bool write, bool sort) {
- if (g_hwndSpin) {
- DestroyWindow(g_hwndSpin);
- g_hwndSpin = NULL;
- }
-
- if (g_hwndEdit) {
- if (g_csdItem == 2) {
- int len = GetWindowTextLength(g_hwndEdit);
- char *s;
-
- if (s = (char *)allocmem(len+1)) {
- GetWindowText(g_hwndEdit, s, len+1);
- g_csdPtr->setPath(s);
- }
- } else {
- char buf[32];
- long lv;
-
- GetWindowText(g_hwndEdit, buf, sizeof buf);
-
- if (1 == sscanf(buf, "%ld", &lv)) {
- if (!g_csdItem) {
- if (lv<-128) lv = -128; else if (lv>127) lv=127;
- g_csdPtr->priority = lv;
- } else {
- if (lv<0) lv=0;
- g_csdPtr->threshold = lv;
- }
- }
- }
- DestroyWindow(g_hwndEdit);
- g_hwndEdit = NULL;
-
- if (sort) {
- SendMessage(g_hwndBox, LVM_REDRAWITEMS, g_index, g_index);
- SendMessage(g_hwndBox, LVM_SORTITEMS, 0, (LPARAM)&LVSorter);
- }
- }
- }
-
- static LRESULT APIENTRY LVEditWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
- WNDPROC wpOld = (WNDPROC)GetWindowLong(hwnd, GWL_USERDATA);
-
- switch(msg) {
- case WM_GETDLGCODE:
- return CallWindowProc(wpOld, hwnd, msg, wParam, lParam) | DLGC_WANTALLKEYS;
- break;
- case WM_KEYDOWN:
- if (wParam == VK_UP) {
- if (g_index > 0)
- LVBeginEdit(g_hwndBox, g_index-1, g_csdItem);
- return 0;
- } else if (wParam == VK_DOWN) {
- if (g_index < SendMessage(g_hwndBox, LVM_GETITEMCOUNT, 0, 0)-1)
- LVBeginEdit(g_hwndBox, g_index+1, g_csdItem);
- return 0;
- } else if (wParam == VK_TAB) {
- if ((SHORT)GetKeyState(VK_SHIFT) < 0) {
- if (g_csdItem > 0)
- LVBeginEdit(g_hwndBox, g_index, g_csdItem-1);
- } else {
- if (g_csdItem < 2)
- LVBeginEdit(g_hwndBox, g_index, g_csdItem+1);
- }
- return 0;
- }
- break;
- case WM_CHAR:
- if (wParam == 0x0d) {
- LVDestroyEdit(true, true);
- return 0;
- } else if (wParam == 0x1b) {
- LVDestroyEdit(false, true);
- return 0;
- }
- break;
- case WM_KILLFOCUS:
- LVDestroyEdit(true, true);
- break;
- case WM_ACTIVATE:
- if (LOWORD(wParam) == WA_INACTIVE)
- if (!g_hwndSpin || (HWND)lParam != g_hwndSpin)
- LVDestroyEdit(true, true);
- break;
- }
- return CallWindowProc(wpOld, hwnd, msg, wParam, lParam);
- }
-
- static void LVBeginEdit(HWND hwndLV, int index, int subitem) {
- RECT r;
- int w=0, w2=0;
- int i;
-
- for(i=0; i<=subitem; i++) {
- w2 += w = SendMessage(hwndLV, LVM_GETCOLUMNWIDTH, i, 0);
- }
-
- LVDestroyEdit(true, false);
-
- g_index = index;
-
- r.left = LVIR_BOUNDS;
-
- SendMessage(hwndLV, LVM_GETITEMRECT, index, (LPARAM)&r);
-
- g_hwndBox = hwndLV;
- g_hwndEdit = CreateWindow("EDIT",
- NULL,
- WS_VISIBLE|WS_CHILD|WS_BORDER | ES_WANTRETURN|ES_AUTOHSCROLL,
- w2-w - 1,
- r.top - 1,
- w + 2,
- r.bottom-r.top + 2,
- hwndLV, (HMENU)1, g_hInst, NULL);
-
- if (g_hwndEdit) {
- LVITEM lvi;
- CapSpillDrive *pcsd;
- char buf[32];
-
- lvi.iItem = index;
- lvi.iSubItem = 0;
- lvi.mask = LVIF_PARAM;
-
- SendMessage(hwndLV, LVM_GETITEM, 0, (LPARAM)&lvi);
-
- g_csdPtr = pcsd = (CapSpillDrive *)lvi.lParam;
- g_csdItem = subitem;
-
- if (subitem<2)
- g_hwndSpin = CreateUpDownControl(WS_VISIBLE|WS_CHILD|UDS_ALIGNRIGHT|UDS_SETBUDDYINT, 0,0,0,0, hwndLV, 1, g_hInst, g_hwndEdit, 127, -128, 0);
-
- guiSubclassWindow(g_hwndEdit, LVEditWndProc);
- SendMessage(g_hwndEdit, WM_SETFONT, SendMessage(hwndLV, WM_GETFONT, 0, 0), MAKELPARAM(FALSE,0));
-
- switch(subitem) {
- case 0:
- sprintf(buf, "%d", pcsd->priority);
- SetWindowText(g_hwndEdit, buf);
- break;
- case 1:
- sprintf(buf, "%d", pcsd->threshold);
- SetWindowText(g_hwndEdit, buf);
- break;
- case 2:
- if (pcsd->path)
- SetWindowText(g_hwndEdit, pcsd->path);
- break;
- }
-
- SetFocus(g_hwndEdit);
- }
- }
-
- static LRESULT APIENTRY LVWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
- WNDPROC wpOld = (WNDPROC)GetWindowLong(hwnd, GWL_USERDATA);
-
- switch(msg) {
- case WM_DESTROY:
- LVDestroyEdit(true, false);
- break;
-
- case WM_GETDLGCODE:
- if (g_hwndEdit)
- return CallWindowProc(wpOld, hwnd, msg, wParam, lParam) | DLGC_WANTALLKEYS;
- else
- return CallWindowProc(wpOld, hwnd, msg, wParam, lParam) | DLGC_DEFPUSHBUTTON;
-
- case WM_CHAR:
- if (wParam == '\r') {
- int index = CallWindowProc(wpOld, hwnd, LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_ALL|LVNI_SELECTED,0));
-
- if (index>=0) {
- LVBeginEdit(hwnd, index, 0);
- }
- }
- break;
-
- case WM_LBUTTONDOWN:
- {
- LVHITTESTINFO htinfo;
- LVITEM lvi;
- int index;
-
- // if this isn't done, the control doesn't gain focus properly...
-
- CallWindowProc(wpOld, hwnd, msg, wParam, lParam);
-
- htinfo.pt.x = 2;
- htinfo.pt.y = HIWORD(lParam);
-
- index = CallWindowProc(wpOld, hwnd, LVM_HITTEST, 0, (LPARAM)&htinfo);
-
- if (index >= 0) {
- int x = LOWORD(lParam);
- int w2=0, w;
- int i=-1;
-
- lvi.state = lvi.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
- CallWindowProc(wpOld, hwnd, LVM_SETITEMSTATE, index, (LPARAM)&lvi);
-
- for(i=0; i<3; i++) {
- w2 += w = CallWindowProc(wpOld, hwnd, LVM_GETCOLUMNWIDTH, i, 0);
- if (x<w2) {
- LVBeginEdit(hwnd, index, i);
-
- return 0;
- }
- }
- }
- LVDestroyEdit(true, false);
- }
- return 0;
- }
- return CallWindowProc(wpOld, hwnd, msg, wParam, lParam);
- }
-